﻿Shader "WastelandWaves/HDRP/Ocean"
{
    Properties
    {
        _OceanColorShallow("Ocean Color Shallow", Color) = (1, 1, 1, 1)
        _OceanColorDeep("Ocean Color Deep", Color) = (1, 1, 1, 1)
        _BubblesColor("Bubbles Color", Color) = (1, 1, 1, 1)
        _Specular("Specular", Color) = (1, 1, 1, 1)
        _DisturbStrength("DisturbStrength", Range(0.0, 100.0)) = 0.4
        _Gloss("Gloss", Range(8.0, 256)) = 20
        _FresnelScale("Fresnel Scale", Range(0, 1)) = 0.5
        _Displace("Displace", 2D) = "black" { }
        _Normal("Normal", 2D) = "black" { }
        _Bubbles("Bubbles", 2D) = "black" { }
        _Disturb("Disturb", 2D) = "black" { }
    }

        HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
        /*
#include "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"
#include "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl"
*/
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl"

// #include "Packages/com.unity.shadergraph/ShaderGraphLibrary/Macros.hlsl"
#define SHADERGRAPH_PREVIEW 1

        CBUFFER_START(UnityPerMaterial)
        CBUFFER_END

        TEXTURE2D(_Displace); SAMPLER(sampler_Displace);
    TEXTURE2D(_Normal); SAMPLER(sampler_Normal);
    TEXTURE2D(_Bubbles); SAMPLER(sampler_Bubbles);
    TEXTURE2D(_Disturb); SAMPLER(sampler_Disturb);
    float4 _OceanColorShallow;
    float4 _OceanColorDeep;
    float4 _BubblesColor;
    float4 _Specular;
    float _Gloss;
    float _FresnelScale;
    float4 _Displace_ST;
    float _DisturbStrength;
        // TEXTURE2D(_SampleTexture2D_C50BEB88_Texture_1); SAMPLER(sampler_SampleTexture2D_C50BEB88_Texture_1); float4 _SampleTexture2D_C50BEB88_Texture_1_TexelSize;

    /*
    struct SurfaceDescriptionInputs
    {
        half4 uv0;
    };


    struct SurfaceDescription
    {
        float4 RGBA_0;
    };

    SurfaceDescription PopulateSurfaceData(SurfaceDescriptionInputs IN)
    {
        SurfaceDescription surface = (SurfaceDescription)0;
        float4 _SampleTexture2D_C50BEB88_RGBA_0 = SAMPLE_TEXTURE2D(_SampleTexture2D_C50BEB88_Texture_1, sampler_SampleTexture2D_C50BEB88_Texture_1, IN.uv0.xy);
        float _SampleTexture2D_C50BEB88_R_4 = _SampleTexture2D_C50BEB88_RGBA_0.r;
        float _SampleTexture2D_C50BEB88_G_5 = _SampleTexture2D_C50BEB88_RGBA_0.g;
        float _SampleTexture2D_C50BEB88_B_6 = _SampleTexture2D_C50BEB88_RGBA_0.b;
        float _SampleTexture2D_C50BEB88_A_7 = _SampleTexture2D_C50BEB88_RGBA_0.a;
        surface.RGBA_0 = $precision4(0, 0, 0, 0);
        return surface;
    }
    */

    inline float2 DisplaceUV(float2 tex, float4 dis) {
        return ((tex.xy) * dis.xy + dis.zw);
    }

    struct GraphVertexInput
    {
        float4 vertex : POSITION;
        float4 texcoord0 : TEXCOORD0;
        UNITY_VERTEX_INPUT_INSTANCE_ID
    };

    GraphVertexInput PopulateVertexData(GraphVertexInput v)
    {
        return v;
    }

    ENDHLSL

        SubShader
    {
        Tags { 
        "RenderPipeline" = "HDRenderPipeline"
        "RenderType" = "HDUnlitShader"
        "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct GraphVertexOutput
            {
                float4 position : POSITION;
                float2 uv : TEXCOORD0;
                float3 positionWS: TEXCOORD1;
                float3 normal: TEXCOORD2;
            };

            GraphVertexOutput vert(GraphVertexInput v)
            {
                //v = PopulateVertexData(v);

                GraphVertexOutput o;
                float4 displace = SAMPLE_TEXTURE2D_LOD(_Displace, sampler_Displace, v.texcoord0.xy, 1.0);
                // float4 displace = tex2Dlod(sampler_Displace, float4(v.texcoord0.xy, 0, 0));
                o.uv = DisplaceUV(v.texcoord0.xy, _Displace_ST);
                v.vertex += float4(displace.xyz, 0);
                //float disturb = (SAMPLE_TEXTURE2D_LOD(_Disturb, sampler_Disturb, o.uv, 1.0).r - 0.5);
                //disturb = sign(disturb) * pow(abs(disturb), 0.3);
                //v.vertex.y += _DisturbStrength * disturb;
                //o.uv = v.texcoord0.xy;

                float3 positionWS = TransformObjectToWorld(v.vertex.xyz);
                o.position = TransformWorldToHClip(positionWS);
                o.positionWS = positionWS;
                o.normal = TransformObjectToWorldNormal(SAMPLE_TEXTURE2D_LOD(_Normal, sampler_Normal, o.uv, 0.0).rgb);
                return o;
            }



            float4 frag(GraphVertexOutput IN) : SV_Target
            {

                DirectionalLightData light = _DirectionalLightDatas[0];
                float  bubbles = SAMPLE_TEXTURE2D(_Bubbles, sampler_Bubbles, IN.uv).r;
                float3 normal =  normalize(TransformObjectToWorldNormal(SAMPLE_TEXTURE2D(_Normal, sampler_Normal, IN.uv).rgb));
                float3 lightDir = -light.forward.xyz;
                float3 viewDir = normalize(GetWorldSpaceNormalizeViewDir(IN.positionWS));
                float3 reflectDir = reflect(-viewDir, normal);
                float3 lightColor = light.color.rgb;

                float fresnel = saturate(_FresnelScale + (1 - _FresnelScale) * pow(1 - dot(normal, viewDir), 5));
                half facing = saturate(dot(viewDir, normal));
                float3 oceanColor = lerp(_OceanColorShallow, _OceanColorDeep, facing).xyz;
                float3 oceanDiffuse = oceanColor * lightColor * saturate(dot(lightDir, normal));
                float3 bubblesDiffuse = _BubblesColor.rbg * lightColor * saturate(dot(lightDir, normal));
                
                float3 halfDir = normalize(lightDir + viewDir);
                float3 specular = lightColor * _Specular.rgb * pow(max(0, dot(normal, halfDir)), _Gloss);
                
                float3 diffuse = lerp(oceanDiffuse, bubblesDiffuse, bubbles);
                float3 ambient = float3(1.f, 1.f, 1.f) * 0.1;
                float3 color = specular * 0.0002 +_OceanColorShallow.rgb; //* fresnel;//+ 0.01 * diffuse * fresnel; // + oceanDiffuse * fresnel + 
                //return float4(fresnel, 0.0, 0.0, 1.0);
                //float3 dbg_disturb = float3(2*(SAMPLE_TEXTURE2D(_Disturb, sampler_Disturb, IN.uv).r - 0.5), 0.0, 0.0);
                return float4(color, 1.0);

                // float4 uv0 = IN.uv0;
                //return float4(1.0, 1.0, 0.0f, 1.f);

                /*
                SurfaceDescriptionInputs surfaceInput = (SurfaceDescriptionInputs)0;
                surfaceInput.uv0 = uv0;

                SurfaceDescription surf = PopulateSurfaceData(surfaceInput);
                return all(isfinite(surf.RGBA_0)) ? half4(surf.RGBA_0.x, surf.RGBA_0.y, surf.RGBA_0.z, 1.0) : float4(1.0f, 0.0f, 1.0f, 1.0f);
                */
            }
            ENDHLSL
        }
    }
}
